package com.aline.ptrscr;

import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.filechooser.FileNameExtensionFilter;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.awt.image.RescaleOp;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.UUID;

public class ScreenConvert extends JWindow {
    private static ScreenConvert instance = null;
    private int orgx, orgy, endx, endy;
    private BufferedImage image = null;
    private BufferedImage tempImage = null;
    private BufferedImage saveImage = null;
    private MouseAdapter mouseAdapter;
    private MouseMotionAdapter mouseMotionAdapter;
    private boolean working = false;

    public static ScreenConvert getInstane() {
        if (instance == null) {
            instance = new ScreenConvert();
        }
        return instance;
    }

    Tools tools = null;
    SimpleDateFormat dateFormat;

    private ScreenConvert() {
        if (dateFormat == null) {
            dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
        }
        this.addKeyListener(new KeyAdapter() {
            @Override
            public void keyReleased(KeyEvent e) {
                System.out.println(e.getKeyCode());
                if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
                    ScreenConvert.this.end();
                }
            }
        });
        if (this.mouseAdapter == null) {
            this.mouseAdapter = new MouseAdapter() {
                @Override
                public void mousePressed(MouseEvent e) {
                    //鼠标松开时记录结束点坐标，并隐藏操作窗口
                    orgx = e.getX();
                    orgy = e.getY();

                    if (tools != null) {
                        tools.setVisible(false);
                    }
                }

                @Override
                public void mouseReleased(MouseEvent e) {
                    //鼠标松开时，显示操作窗口
                    if (tools == null) {
                        tools = new Tools(ScreenConvert.this, e.getX(), e.getY());
                    } else {
                        tools.setLocation(e.getX(), e.getY());
                    }
                    tools.requestFocus();
                    tools.setVisible(true);
                    tools.toFront();
                }
            };
        }
        if (this.mouseMotionAdapter == null) {
            this.mouseMotionAdapter = new MouseMotionAdapter() {

                @Override
                public void mouseDragged(MouseEvent e) {
                    //鼠标拖动时，记录坐标并重绘窗口
                    endx = e.getX();
                    endy = e.getY();

                    //临时图像，用于缓冲屏幕区域放置屏幕闪烁
                    Image tempImage2 = createImage(ScreenConvert.this.getWidth(), ScreenConvert.this.getHeight());
                    Graphics g = tempImage2.getGraphics();
                    g.drawImage(tempImage, 0, 0, null);
                    int x = Math.min(orgx, endx);
                    int y = Math.min(orgy, endy);
                    int width = Math.abs(endx - orgx) + 1;
                    int height = Math.abs(endy - orgy) + 1;
                    // 加上1防止width或height0
                    g.setColor(Color.BLUE);
                    g.drawRect(x - 1, y - 1, width + 1, height + 1);
                    //减1加1都了防止图片矩形框覆盖掉
                    saveImage = image.getSubimage(x, y, width, height);
                    g.drawImage(saveImage, x, y, null);

                    ScreenConvert.this.getGraphics().drawImage(tempImage2, 0, 0, ScreenConvert.this);
                }
            };
        }
    }

    public void start() throws Exception {
        if (working) {
            return;
        }
        //获取屏幕尺寸
        Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
        this.setBounds(0, 0, d.width, d.height);
        //截取屏幕
        Robot robot = new Robot();
        image = robot.createScreenCapture(new Rectangle(0, 0, d.width, d.height));
        // 监听
        this.addMouseListener(mouseAdapter);
        // 监听
        this.addMouseMotionListener(this.mouseMotionAdapter);
        this.setVisible(true);
        this.setAlwaysOnTop(true);
    }

    @Override
    public void setVisible(boolean b) {
        super.setVisible(b);
        this.working = b;
        if (b)
            this.requestFocus();
    }

    @Override
    public void paint(Graphics g) {
        RescaleOp ro = new RescaleOp(0.8f, 0, null);
        tempImage = ro.filter(image, null);
        g.drawImage(tempImage, 0, 0, this);
    }

    //保存图像到文件
    public void saveImage() throws IOException {
        try {
            if (Config.isAutoSave()) {
                String path = Config.getSavePath();
                String fileName = null;
                String fileType = Config.getType();
                String fileNameRule = Config.getFileNameRule();
                if (Config.RANDM_NAME.equals(fileNameRule)) {
                    fileName = UUID.randomUUID().toString().replaceAll("-", "") + fileType;
                } else {
                    fileName = dateFormat.format(System.currentTimeMillis()) + fileType;
                }
                File saveFile = null;
                try {
                    saveFile = new File(path + File.separator + fileName);
                } catch (Exception e) {
                    saveFile = new File(System.getProperty("user.dir") + File.separator + fileName);
                }
                ImageIO.write(saveImage, fileType.substring(1), saveFile);
            } else {
                showImageSaver();
            }
        } finally {
            end();
        }
    }

    public void showImageSaver() throws IOException {
        try {
            tools.setAlwaysOnTop(false);
            JFileChooser jfc = new JFileChooser();
            jfc.setDialogTitle("保存");
            String prefix = System.getProperty("user.dir");
            String fileName = dateFormat.format(System.currentTimeMillis());
            String suffix = ".png";
            File defaultFile = new File(prefix + File.separator + fileName + suffix);

            FileNameExtensionFilter filter = new FileNameExtensionFilter("png", "png");
            jfc.addChoosableFileFilter(filter);
            jfc.addChoosableFileFilter(new FileNameExtensionFilter("jpeg", "jpeg"));
            jfc.addChoosableFileFilter(new FileNameExtensionFilter("jpg", "jpg"));
            jfc.setSelectedFile(defaultFile);

            int flag = jfc.showSaveDialog(this);
            if (flag == JFileChooser.APPROVE_OPTION) {
                String fileType = jfc.getFileFilter().getDescription();
                File file = jfc.getSelectedFile();
                String path = file.getPath();
                //检查文件后缀，放置用户忘记输入后缀或者输入不正确的后缀
                if (fileType.equals("所有文件")) {
                    fileType = "png";
                }
                if (!path.endsWith(fileType)) {
                    path += ".png";
                }
                //写入文件
                ImageIO.write(saveImage, fileType, new File(path));
            }
        } finally {
            end();
        }
    }

    void end() {
        // 关闭监听、释放资源、隐藏窗口
        this.removeMouseListener(mouseAdapter);
        this.removeMouseMotionListener(mouseMotionAdapter);
        this.tempImage = null;
        this.image = null;
        this.saveImage = null;
        tools.setVisible(false);
        this.setVisible(false);
    }

    public boolean isWorking() {
        return working;
    }
}
